﻿\subsection{Laden einer 32-Bit-Konstante in ein Register}
\label{MIPS_big_constants}

\begin{lstlisting}[style=customc]
unsigned int f()
{
	return 0x12345678;
};
\end{lstlisting}

Alle Anweisungen in MIPS sind genau wie bei ARM 32-Bit groß. Somit ist es nicht
möglich eine 32-Bit-Variable in einer Anweisung unterzubringen.
\myindex{MIPS!\Instructions!LI}
\myindex{MIPS!\Instructions!ORI}

Dementsprechen müssen mindestens zwei Anweisungen genutzt werden:
die erste läd den höherwertigen Teil der 32-Bit-Zahl und die zweite führt eine
ODER-Anweisung aus, welche den niederwertigen 16-Bit-Teil des Zielregisters setzt:rget register:

\begin{lstlisting}[caption=GCC 4.4.5 -O3 (\assemblyOutput),style=customasmMIPS]
        li      $2,305397760  # 0x12340000
        j       $31
        ori     $2,$2,0x5678 ; branch delay slot
\end{lstlisting}

\IDA kennt dieses oft genutzte Muster sehr gut. Aus Gründen der Übersichtlichkeit
wird hier die letzte \INS{ORI}-Anweisung als \INS{LI}-Pseudo-Anweisung angezeigt,
welche vermeintlich eine komplette 32-Bit-Zahl in das \$V0-Register läd.

\myindex{MIPS!\Instructions!LUI}

\begin{lstlisting}[caption=GCC 4.4.5 -O3 (IDA),style=customasmMIPS]
         lui     $v0, 0x1234
         jr      $ra
         li      $v0, 0x12345678 ; branch delay slot
\end{lstlisting}

Die GCC-Assembler-Ausgabe beinhaltet ebenfalls die LI-Pseudo-Anweisung, allerdings
ist hier auch die Anweisung \INS{LUI} (\q{Load Upper Immediate}), die einen 16-Bit-Wert
im höherwertigen Teil des Registers sichert.

Nachfolgend die \IT{objdump}-Ausgabe:

\begin{lstlisting}[caption=objdump,style=customasmMIPS]
00000000 <f>:
   0:   3c021234        lui     v0,0x1234
   4:   03e00008        jr      ra
   8:   34425678        ori     v0,v0,0x5678
\end{lstlisting}

\subsubsection{Laden einer globalen 32-Bit-Variable in ein Register}

\begin{lstlisting}[style=customc]
unsigned int global_var=0x12345678;

unsigned int f2()
{
        return global_var;
};
\end{lstlisting}

\myindex{MIPS!\Instructions!LW}

Dies ist leicht unterschiedlich: \INS{LUI} läd die oberen 16 Bit von \IT{global\_var}
in \$2 (or \$V0). Anschließend läd \INS{LW} die unteren 16 Bit und addiert sie mit
dem Inhalt von \$2:

\begin{lstlisting}[caption=GCC 4.4.5 -O3 (\assemblyOutput),style=customasmMIPS]
f2:
        lui     $2,%hi(global_var)
        lw      $2,%lo(global_var)($2)
        j       $31
        nop	; branch delay slot

	...

global_var:
        .word   305419896
\end{lstlisting}

\IDA kennt auch das oft genutzte Anweisungspaar \INS{LUI}/\INS{LW} und fasst beide
in der einzelten Anweisung \INS{LW} zusammen:

\begin{lstlisting}[caption=GCC 4.4.5 -O3 (IDA),style=customasmMIPS]
_f2:
                lw      $v0, global_var
                jr      $ra
                or      $at, $zero	; branch delay slot

		...

                .data
                .globl global_var
global_var:     .word 0x12345678         # DATA XREF: _f2
\end{lstlisting}

Die Ausgabe von \IT{objdump} ist die selbe wie die Assembler-Ausgabe von GCC.
Nachfolgend die Speicherauszüge der Objektdateien:

\begin{lstlisting}[caption=objdump,style=customasmMIPS]
objdump -D filename.o

...

0000000c <f2>:
   c:   3c020000        lui     v0,0x0
  10:   8c420000        lw      v0,0(v0)
  14:   03e00008        jr      ra
  18:   00200825        move    at,at	; branch delay slot
  1c:   00200825        move    at,at

Disassembly of section .data:

00000000 <global_var>:
   0:   12345678        beq     s1,s4,159e4 <f2+0x159d8>

...

objdump -r filename.o

...

RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE
0000000c R_MIPS_HI16       global_var
00000010 R_MIPS_LO16       global_var

...

\end{lstlisting}

Es ist zu sehen, dass die Adresse von \IT{global\_var} direkt mit den Anweisungen
\INS{LUI} und \INS{LW} beim Laden der ausführbaren Datei geschrieben wird:
der höherwertige 16-Bit-Teil von \IT{global\_var} mit der ersten Anweisung (\INS{LUI}),
der niederwertige 16-Bit-Teil mit der zweiten Anweisung (\INS{LW}).
